package org.community.test.service;

import cn.hutool.core.io.file.FileReader;
import io.minio.Result;
import io.minio.messages.DeleteError;
import lombok.Data;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.IOUtils;
import org.community.test.repositary.util.MinioUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.List;
import java.util.Map;

@Service
@Data
@Slf4j
public class VideoService {

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private FileUtil fileUtil;


    public String uploadToM3u8(String fileName,String infoUrlPrefix) throws Exception {
        String videoFolderNamePrefix = "video/";
        String fileNamePrefix = this.getFileUtil().fileNameTakeApart(fileName).get("prefix");
        String minioFolder = videoFolderNamePrefix+fileNamePrefix+"/";
        InputStream in = new ByteArrayInputStream(this.getMinioUtil().download(minioFolder,fileName));

        //缓存文件夹根目录名
        String cacheDirName = "video_cache";
        //生成切片缓存文件夹
        String cachePrefix = this.getFileUtil().makeCacheDir(fileNamePrefix,cacheDirName);
        log.info("缓存目录：{}",cachePrefix);
        String m3u8Url = cachePrefix + fileNamePrefix+".m3u8";
        boolean transformOver = false;
        if(infoUrlPrefix == null){
            transformOver =  FFmpegProcessor.convertMediaToM3u8ByHttp(in,
                    m3u8Url,
                    cachePrefix,
                    fileNamePrefix
            );
        }
        transformOver = FFmpegProcessor.convertMediaToM3u8ByHttp(in,
                m3u8Url,
                infoUrlPrefix,
                cachePrefix,
                fileNamePrefix
        );
        log.info("切片生成结果：{}",transformOver);
        if(transformOver){
            log.info("开始上传服务器");
            FileUtil fileUtil = this.getFileUtil();
            //切片文件清单
            Map<String,File> fileList= fileUtil.getFolderFileList(cachePrefix);
            //multipartFile文件
            Map<String,MultipartFile> multipartFiles = new HashMap<>();
            //读取生成的切片缓存并上传到云端
            for(Map.Entry<String,File> entry: fileList.entrySet()){
                FileItem fileItem = fileUtil.getMultipartFile(entry.getValue(),cachePrefix);
                MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
                String minioFileName = videoFolderNamePrefix + fileNamePrefix +"/" +entry.getKey();
                log.info("已生成MultipartFile,云路径：{}",minioFileName);
                multipartFiles.put(minioFileName,multipartFile);
            }

            this.getMinioUtil().uploadByBatch(multipartFiles);



        }
        //删除切片缓存
        cn.hutool.core.io.FileUtil.del(cachePrefix);
        //删除云端源视频
        String minioDeleteObjectPath = minioFolder+fileName;
        log.info("源视频云端路径:{}",minioDeleteObjectPath);
        List<String> objectDel = new ArrayList<>();
        objectDel.add(minioDeleteObjectPath);
        Iterable<Result<DeleteError>> delMessages = this.getMinioUtil().removeObjects(objectDel);
        while(delMessages.iterator().hasNext()){
            log.info(String.valueOf(delMessages.iterator().next()));
        }
        return fileNamePrefix+".m3u8";

    }

    public String uploadToM3u8(String fileName) throws Exception{
        return uploadToM3u8(fileName,null);
    }





    public void upload(String fileName,MultipartFile multipartFile) {
        String videoFolderNamePrefix = "video/";
        String fileNamePrefix = this.getFileUtil().fileNameTakeApart(fileName).get("prefix");
        String minioFileName = videoFolderNamePrefix+fileNamePrefix+"/"+fileName;
        this.getMinioUtil().upload(multipartFile,minioFileName);
    }


    /**
     * 预览加密文件
     */

    public ResponseEntity<byte[]> preview(String fileName) {
        byte[] bytes= this.getMinioUtil().download("video/",fileName);
        return this.getMinioUtil().bytesToResponseEntity(bytes,fileName);
    }

    /**
     * 预览加密文件
     */

    public ResponseEntity<byte[]> download(String fileName) {
       return preview(fileName);
    }


    public ResponseEntity<byte[]> videoPlayCloud(String videoName) {
        String videoNamePrefix = fileUtil.fileNameTakeApart(videoName).get("prefix");
        byte[] bytes= this.getMinioUtil().download("video/"+videoNamePrefix+"/",videoName);
        return this.getMinioUtil().bytesToResponseEntityVideo(bytes,videoName);
    }



}
